#include <stdio.h>
#include <stdbool.h>

#define N 30

int rol[N]; // 存储每一行剩余可走步数
int col[N]; // 存储每一列剩余可走步数
int n;
bool flag[N][N]; // 标记数组，用于标记某个位置是否已经走过
// 分别存储已经走过的路径的横纵坐标
int resX[1000];
int resY[1000];
int resCount = 0; // 记录已经走过的路径数量
// 分别表示在横向和纵向移动时的四个方向：右，下，上，左
int dx[] = {0, 1, -1, 0}; // 下1上-1
int dy[] = {1, 0, 0, -1}; // 右1左-1
// 检查当前位置是否符合要求，如果当前位置是终点且所有行和列都已经走完，则输出路径并返回false，否则返回true
bool check(int x, int y)
{
	if (x == n && y == n)
	{
		for (int i = 1; i <= n; i++)
		{
			if (col[i] != 0)
			{
				return false;
			}
		}
		for (int i = 1; i <= n; i++)
		{
			if (rol[i] != 0)
			{
				return false;
			}
		}
		for (int i = 0; i < resCount; i++)
		{
			int x2 = resX[i];
			int y2 = resY[i];
			int sum = n * (x2 - 1) + y2 - 1;
			printf("%d ", sum);
		}
		printf("\n");
		return false;
	}
	return true;
}
// 判断下一个位置是否可行，如果下一个位置 超出边界 或 已经走过 或 剩余步数不足，则返回false,否则返回true
bool pd(int x2, int y2)
{
	if (flag[x2][y2] || x2 < 1 || x2 > n || y2 < 1 || y2 > n || col[x2] <= 0 || rol[y2] <= 0)
	{
		return false;
	}
	return true;
}
// 深度优先搜索函数，用于递归的搜索所有可能的路径。
// 在每一步中，先检查当前位置是否符合要求，如果符合则据徐向四个方向探索，直到找到一条完整路径或无法继续探索为止
void dfs(int x, int y)
{
	if (!check(x, y))//如果不符合条件，直接返回
	{
		return;
	}
	else
	{
		for (int i = 0; i < 4; i++)//遍历四个方向（上下左右）来尝试移动
		{
			//每一个方向计算新的xt和yt
			int xt = dx[i] + x;
			int yt = dy[i] + y;
			if (!pd(xt, yt))//用pd函数来判断新位置是否合法
			{
				continue;
			}
			else//合法
			{
				flag[xt][yt] = true;
				col[xt]--;
				rol[yt]--;
				resX[resCount] = xt;
				resY[resCount++] = yt;
				dfs(xt, yt);
				//当递归调用返回后，代码会将之前做出的改变恢复到原始状态，即将新位置的标记、计数器和坐标数组恢复到递归前的状态，以便进行下一次搜索。
				resCount--;
				flag[xt][yt] = false;
				col[xt]++;
				rol[yt]++;
			}
		}
	}
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		scanf("%d", &rol[i]);
	for (int i = 1; i <= n; i++)
		scanf("%d", &col[i]);
	// 从起点（1，1）开始调用dfs函数进行探索，最终输出所有可能的路径
	flag[1][1] = true;
	col[1]--;
	rol[1]--;
	resX[resCount] = 1;
	resY[resCount++] = 1;
	dfs(1, 1);
	return 0;
}
